using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace MaterialUI
{
	[ExecuteInEditMode]
	[AddComponentMenu("MaterialUI/TabView", 100)]
	public class TabView : UIBehaviour
	{
		[SerializeField]
		private float m_ShrinkTabsToFitThreshold = 16f;

		[SerializeField]
		private bool m_ForceStretchTabsOnLanscape;

		[SerializeField]
		private RectTransform m_TabsContainer;

		[SerializeField]
		private TabPage[] m_Pages;

		[SerializeField]
		private int m_CurrentPage;

		[SerializeField]
		private TabItem m_TabItemTemplate;

		[SerializeField]
		private RectTransform m_PagesContainer;

		[SerializeField]
		private RectTransform m_PagesRect;

		[SerializeField]
		private RectTransform m_Indicator;

		private ScrollRect m_PagesScrollRect;

		private float m_TabWidth;

		private float m_TabPadding = 12f;

		private TabItem[] m_Tabs;

		[SerializeField]
		private bool m_LowerUnselectedTabAlpha = true;

		[SerializeField]
		private bool m_CanScrollBetweenTabs = true;

		private RectTransform m_RectTransform;

		private int m_IndicatorTweener;

		private int m_TabsContainerTweener;

		private int m_PagesContainerTweener;

		private Vector2 m_PageSize;

		private bool m_AlreadyInitialized;

		public float shrinkTabsToFitThreshold
		{
			get
			{
				return m_ShrinkTabsToFitThreshold;
			}
			set
			{
				m_ShrinkTabsToFitThreshold = value;
			}
		}

		public bool forceStretchTabsOnLanscape
		{
			get
			{
				return m_ForceStretchTabsOnLanscape;
			}
			set
			{
				m_ForceStretchTabsOnLanscape = value;
			}
		}

		public RectTransform tabsContainer
		{
			get
			{
				return m_TabsContainer;
			}
			set
			{
				m_TabsContainer = value;
			}
		}

		public TabPage[] pages
		{
			get
			{
				return m_Pages;
			}
			set
			{
				m_Pages = value;
			}
		}

		public int currentPage
		{
			get
			{
				return m_CurrentPage;
			}
			set
			{
				m_CurrentPage = value;
			}
		}

		public TabItem tabItemTemplate
		{
			get
			{
				return m_TabItemTemplate;
			}
			set
			{
				m_TabItemTemplate = value;
			}
		}

		public RectTransform pagesContainer
		{
			get
			{
				return m_PagesContainer;
			}
			set
			{
				m_PagesContainer = value;
			}
		}

		public RectTransform pagesRect
		{
			get
			{
				return m_PagesRect;
			}
			set
			{
				m_PagesRect = value;
			}
		}

		public RectTransform indicator
		{
			get
			{
				return m_Indicator;
			}
			set
			{
				m_Indicator = value;
			}
		}

		public ScrollRect pagesScrollRect
		{
			get
			{
				if (m_PagesScrollRect == null)
				{
					m_PagesScrollRect = m_PagesRect.GetComponent<ScrollRect>();
				}
				return m_PagesScrollRect;
			}
		}

		public float tabWidth => m_TabWidth;

		public float tabPadding
		{
			get
			{
				return m_TabPadding;
			}
			set
			{
				m_TabPadding = value;
			}
		}

		public TabItem[] tabs => m_Tabs;

		public bool lowerUnselectedTabAlpha
		{
			get
			{
				return m_LowerUnselectedTabAlpha;
			}
			set
			{
				m_LowerUnselectedTabAlpha = value;
			}
		}

		public bool canScrollBetweenTabs
		{
			get
			{
				return m_CanScrollBetweenTabs;
			}
			set
			{
				m_CanScrollBetweenTabs = value;
				pagesScrollRect.enabled = value;
				OverscrollConfig component = pagesScrollRect.GetComponent<OverscrollConfig>();
				if (component != null)
				{
					component.enabled = value;
				}
			}
		}

		public RectTransform rectTransform
		{
			get
			{
				if (m_RectTransform == null)
				{
					m_RectTransform = (RectTransform)base.transform;
				}
				return m_RectTransform;
			}
		}

		protected override void Start()
		{
			if (Application.isPlaying)
			{
				InitializeTabs();
				InitializePages();
			}
			MaterialUIScaler parentScaler = MaterialUIScaler.GetParentScaler(base.transform);
			parentScaler.OnOrientationChange = (MaterialUIScaler.OrientationChangeEvent)Delegate.Combine(parentScaler.OnOrientationChange, (MaterialUIScaler.OrientationChangeEvent)delegate
			{
				if (Application.isPlaying)
				{
					InitializeTabs();
					InitializePages();
				}
			});
		}

		public void InitializeTabs()
		{
			if (m_AlreadyInitialized)
			{
				for (int i = 0; i < m_Tabs.Length; i++)
				{
					UnityEngine.Object.Destroy(m_Tabs[i].gameObject);
				}
				m_TabItemTemplate.gameObject.SetActive(value: true);
				LayoutRebuilder.ForceRebuildLayoutImmediate(this.rectTransform);
			}
			Vector2 properSize = this.rectTransform.GetProperSize();
			float x = properSize.x;
			m_TabWidth = GetMaxTabTextWidth() + 2f * m_TabPadding;
			m_TabsContainer.GetComponent<LayoutElement>().minWidth = x;
			m_TabsContainer.GetComponent<ContentSizeFitter>().enabled = true;
			float num = m_TabWidth * (float)m_Pages.Length;
			m_TabsContainer.GetComponent<HorizontalLayoutGroup>().childForceExpandWidth = true;
			m_TabItemTemplate.GetComponent<LayoutElement>().minWidth = 72f;
			if (Screen.width > Screen.height && !m_ForceStretchTabsOnLanscape)
			{
				if (Mathf.Abs(num - x) < m_ShrinkTabsToFitThreshold)
				{
					m_TabWidth = x / (float)m_Pages.Length;
				}
				else
				{
					m_TabsContainer.GetComponent<HorizontalLayoutGroup>().childForceExpandWidth = false;
					m_TabItemTemplate.GetComponent<LayoutElement>().minWidth = 160f;
				}
			}
			else if (num - x < m_ShrinkTabsToFitThreshold)
			{
				m_TabWidth = x / (float)m_Pages.Length;
			}
			m_TabWidth = Mathf.Max(m_TabWidth, m_TabItemTemplate.GetComponent<LayoutElement>().minWidth);
			m_TabItemTemplate.GetComponent<LayoutElement>().preferredWidth = m_TabWidth;
			m_Indicator.anchorMin = new Vector2(0f, 0f);
			m_Indicator.anchorMax = new Vector2(0f, 0f);
			m_Indicator.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, m_TabWidth);
			m_Tabs = new TabItem[m_Pages.Length];
			for (int j = 0; j < m_Pages.Length; j++)
			{
				TabItem component = UnityEngine.Object.Instantiate(m_TabItemTemplate.gameObject).GetComponent<TabItem>();
				component.rectTransform.SetParent(m_TabItemTemplate.transform.parent);
				component.rectTransform.localScale = Vector3.one;
				component.rectTransform.localEulerAngles = Vector3.zero;
				RectTransform rectTransform = component.rectTransform;
				Vector3 localPosition = component.rectTransform.localPosition;
				float x2 = localPosition.x;
				Vector3 localPosition2 = component.rectTransform.localPosition;
				rectTransform.localPosition = new Vector3(x2, localPosition2.y, 0f);
				component.id = j;
				if (!string.IsNullOrEmpty(m_Pages[j].tabName))
				{
					component.name = m_Pages[j].tabName;
					if (component.itemText != null)
					{
						component.itemText.text = component.name.ToUpper();
					}
				}
				else
				{
					component.name = "Tab " + j;
					if (component.itemText != null)
					{
						component.itemText.enabled = false;
					}
				}
				component.SetupGraphic(m_Pages[j].tabIcon.imageDataType);
				if (component.itemIcon != null)
				{
					if (m_Pages[j].tabIcon != null)
					{
						component.itemIcon.SetImage(m_Pages[j].tabIcon);
					}
					else
					{
						component.itemIcon.enabled = false;
					}
				}
				m_Tabs[j] = component;
			}
			m_TabItemTemplate.gameObject.SetActive(value: false);
			m_TabsContainer.anchorMin = Vector2.zero;
			m_TabsContainer.anchorMax = new Vector2(0f, 1f);
			OverscrollConfig component2 = m_TabsContainer.parent.GetComponent<OverscrollConfig>();
			if (component2 != null)
			{
				component2.Setup();
			}
			m_AlreadyInitialized = true;
		}

		private void InitializePages()
		{
			if (m_Pages.Length > 0)
			{
				for (int i = 0; i < m_Pages.Length; i++)
				{
					m_Pages[i].gameObject.SetActive(value: true);
				}
			}
			m_PageSize = m_PagesRect.GetProperSize();
			for (int j = 0; j < m_Pages.Length; j++)
			{
				RectTransform rectTransform = m_Pages[j].rectTransform;
				rectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, (float)j * m_PageSize.x, m_PageSize.x);
			}
			m_PagesContainer.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0f, m_PageSize.x * (float)m_Pages.Length);
			OverscrollConfig component = m_PagesRect.GetComponent<OverscrollConfig>();
			if (component != null)
			{
				component.Setup();
			}
			SetPage(m_CurrentPage, animate: false);
		}

		private float GetMaxTabTextWidth()
		{
			float num = 0f;
			if (m_TabItemTemplate.itemText != null)
			{
				TextGenerator cachedTextGeneratorForLayout = m_TabItemTemplate.itemText.cachedTextGeneratorForLayout;
				TextGenerationSettings generationSettings = m_TabItemTemplate.itemText.GetGenerationSettings(new Vector2(float.MaxValue, float.MaxValue));
				for (int i = 0; i < m_Pages.Length; i++)
				{
					num = Mathf.Max(num, cachedTextGeneratorForLayout.GetPreferredWidth(m_Pages[i].name.ToUpper(), generationSettings));
				}
			}
			return num;
		}

		public void SetPage(int index)
		{
			SetPage(index, animate: true);
		}

		public void SetPage(int index, bool animate)
		{
			index = Mathf.Clamp(index, 0, m_Pages.Length - 1);
			TweenIndicator(index, animate);
			TweenTabsContainer(index, animate);
			TweenPagesContainer(index, animate);
			if (!m_LowerUnselectedTabAlpha)
			{
				return;
			}
			if (animate)
			{
				for (int j = 0; j < m_Tabs.Length; j++)
				{
					int i = j;
					TweenManager.TweenFloat(delegate(float f)
					{
						m_Tabs[i].canvasGroup.alpha = f;
					}, () => m_Tabs[i].canvasGroup.alpha, () => (!m_Pages[i].interactable) ? 0.15f : ((i != index) ? 0.5f : 1f), 0.5f);
				}
			}
			else
			{
				for (int k = 0; k < m_Tabs.Length; k++)
				{
					m_Tabs[k].canvasGroup.alpha = ((!m_Pages[k].interactable) ? 0.15f : ((k != index) ? 0.5f : 1f));
				}
			}
		}

		private void OnPagesTweenEnd()
		{
			for (int i = 0; i < m_Pages.Length; i++)
			{
				if (i >= m_CurrentPage - 1 && i <= m_CurrentPage + 1)
				{
					m_Pages[i].gameObject.SetActive(value: true);
				}
				else
				{
					m_Pages[i].DisableIfAllowed();
				}
			}
		}

		private void TweenPagesContainer(int index, bool animate = true)
		{
			for (int i = 0; i < m_Pages.Length; i++)
			{
				int num = Mathf.Min(m_CurrentPage, index);
				int num2 = Mathf.Max(m_CurrentPage, index);
				if (i >= num - 1 && i <= num2 + 1)
				{
					m_Pages[i].gameObject.SetActive(value: true);
				}
				else
				{
					m_Pages[i].DisableIfAllowed();
				}
			}
			float value = 0f - (float)index * m_PageSize.x;
			value = Mathf.Clamp(value, 0f - (float)m_Pages.Length * m_PageSize.x, 0f);
			TweenManager.EndTween(m_PagesContainerTweener);
			m_CurrentPage = index;
			if (animate)
			{
				m_PagesContainerTweener = TweenManager.TweenVector2(delegate(Vector2 vector2)
				{
					m_PagesContainer.anchoredPosition = vector2;
				}, m_PagesContainer.anchoredPosition, new Vector2(value, 0f), 0.5f);
				return;
			}
			m_PagesContainer.anchoredPosition = new Vector2(value, 0f);
			OnPagesTweenEnd();
		}

		private void TweenTabsContainer(int index, bool animate = true)
		{
			float num = 0f - (float)index * m_TabWidth;
			float num2 = num;
			Vector2 properSize = rectTransform.GetProperSize();
			num = num2 + properSize.x / 2f;
			num -= m_TabWidth / 2f;
			float value = num;
			float num3 = 0f - LayoutUtility.GetPreferredWidth(m_TabsContainer);
			Vector2 properSize2 = rectTransform.GetProperSize();
			num = Mathf.Clamp(value, num3 + properSize2.x, 0f);
			TweenManager.EndTween(m_TabsContainerTweener);
			if (animate)
			{
				m_TabsContainerTweener = TweenManager.TweenVector2(delegate(Vector2 vector2)
				{
					m_TabsContainer.anchoredPosition = vector2;
				}, m_TabsContainer.anchoredPosition, new Vector2(num, 0f), 0.5f);
			}
			else
			{
				m_TabsContainer.anchoredPosition = new Vector2(num, 0f);
			}
		}

		private void TweenIndicator(int targetTab, bool animate = true)
		{
			float x = (float)targetTab * m_TabWidth;
			TweenManager.EndTween(m_IndicatorTweener);
			if (animate)
			{
				m_IndicatorTweener = TweenManager.TweenVector2(delegate(Vector2 vector2)
				{
					m_Indicator.anchoredPosition = vector2;
				}, m_Indicator.anchoredPosition, new Vector2(x, 0f), 0.5f);
			}
			else
			{
				m_Indicator.anchoredPosition = new Vector2(x, 0f);
			}
		}

		public void TabItemPointerDown(int id)
		{
			TweenManager.EndTween(m_TabsContainerTweener);
		}

		public void TabPagePointerUp(float delta)
		{
			if (m_CanScrollBetweenTabs)
			{
				pagesScrollRect.velocity = Vector2.zero;
				if (Mathf.Abs(delta) < 1f)
				{
					SetPage(NearestPage());
				}
				else if (delta < 0f)
				{
					SetPage(NearestPage(1));
				}
				else
				{
					SetPage(NearestPage(-1));
				}
			}
		}

		private int NearestPage(int direction = 0)
		{
			Vector2 anchoredPosition = m_PagesContainer.anchoredPosition;
			float num = 0f - anchoredPosition.x;
			if (direction < 0)
			{
				return Mathf.FloorToInt(num / m_PageSize.x);
			}
			if (direction > 0)
			{
				return Mathf.CeilToInt(num / m_PageSize.x);
			}
			return Mathf.RoundToInt(num / m_PageSize.x);
		}

		public void TabPageDrag()
		{
			if (m_CanScrollBetweenTabs)
			{
				if (TweenManager.TweenIsActive(m_PagesContainerTweener))
				{
					TweenManager.EndTween(m_PagesContainerTweener);
					m_CurrentPage = NearestPage();
					OnPagesTweenEnd();
					TweenIndicator(m_CurrentPage);
				}
				TweenManager.EndTween(m_IndicatorTweener);
				Vector2 anchoredPosition = m_PagesContainer.anchoredPosition;
				float num = (0f - anchoredPosition.x) / (m_PageSize.x * (float)m_Pages.Length);
				m_Indicator.anchoredPosition = new Vector2(m_TabWidth * (float)m_Tabs.Length * num, 0f);
			}
		}
	}
}
